/*
 * 
 * Libman
 * 
 * Daniel Kaufmann, Martin Lang, Simon Moosbrugger,
 * Stefan Mayer, Stephan Halbeisen
 * 
 */
package model.dao;

import hibernate.HibernateUtil;

import org.hibernate.Session;

/**
 * A Factory which provides instances for all DAOs.
 */
public class DAOFactory {
	
	/** The _instance. */
	private static DAOFactory _instance;

	/**
	 * Returns the globally useable {@link DAOFactory}.
	 * 
	 * @return the instance.
	 */
	public static DAOFactory getInstance() {
		if (_instance == null) {
			_instance = new DAOFactory();
		}
		return _instance;
	}

	/**
	 * Returns a new DAO for managing {@link Book} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public BookDAO getBookDAO() {
		return (BookDAO) instantiateDAO(BookDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Cd} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public CdDAO getCdDAO() {
		return (CdDAO) instantiateDAO(CdDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link StartClient} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public ClientDAO getClientDAO() {
		return (ClientDAO) instantiateDAO(ClientDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Department} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public DepartmentDAO getDepartmentDAO() {
		return (DepartmentDAO) instantiateDAO(DepartmentDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Dvd} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public DvdDAO getDvdDAO() {
		return (DvdDAO) instantiateDAO(DvdDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Exemplar} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public ExemplarDAO getExemplarDAO() {
		return (ExemplarDAO) instantiateDAO(ExemplarDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Group} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public GroupDAO getGroupDAO() {
		return (GroupDAO) instantiateDAO(GroupDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Language} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public LanguageDAO getLanguageDAO() {
		return (LanguageDAO) instantiateDAO(LanguageDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Loan} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public LoanDAO getLoanDAO() {
		return (LoanDAO) instantiateDAO(LoanDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link MediumContainer} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public MediumDAO getMediumDAO() {
		return (MediumDAO) instantiateDAO(MediumDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link PersonData} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public PersonDataDAO getPersonDataDAO() {
		return (PersonDataDAO) instantiateDAO(PersonDataDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link PersonType} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public PersonTypeDAO getPersonTypeDAO() {
		return (PersonTypeDAO) instantiateDAO(PersonTypeDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Reservation} Objects.
	 * 
	 * @return a new {@link CheckOperatorDAO} instance.
	 */
	public ReservationDAO getReservationDAO() {
		return (ReservationDAO) instantiateDAO(ReservationDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Keyword} Objects.
	 * 
	 * @return a new {@link KeywordDAO} instance.
	 */
	public KeywordDAO getKeywordDAO() {
		return (KeywordDAO) instantiateDAO(KeywordDAO.class);
	}

	/**
	 * Returns a new DAO for managing {@link Role} Objects.
	 * 
	 * @return a new {@link RoleDAO} instance.
	 */
	public RoleDAO getRoleDAO() {
		return (RoleDAO) instantiateDAO(RoleDAO.class);
	}
	
	/**
	 * Returns a new DAO for managing {@link User} Objects.
	 * 
	 * @return a new {@link UserDAO} instance.
	 */
	public UserDAO getUserDAO() {
		return (UserDAO) instantiateDAO(UserDAO.class);
	}
	/**
	 * Creates a new DAO for the specified class.
	 * 
	 * @param daoClass
	 *            the type of the dao to be created
	 * @return the created an initialized dao.
	 */
	private GenericHibernateDAO<?, ?> instantiateDAO(Class<?> daoClass) {
		try {
			GenericHibernateDAO<?, ?> dao = (GenericHibernateDAO<?, ?>) daoClass
					.newInstance();
			dao.setSession(getCurrentSession());
			return dao;
		} catch (Exception ex) {
			throw new RuntimeException("Can not instantiate DAO: " + daoClass,
					ex);
		}
	}

	/**
	 * Returns the current session to be assigned to all DAOs.
	 * 
	 * @return the current session.
	 */
	// You could override this if you don't want HibernateUtil for lookup
	protected Session getCurrentSession() {
		return HibernateUtil.currentSession();
	}
}